package main
import (
	"fmt"
	"time"
	"sync"
)

// 示例二
func write(ch chan int) {
	for i := 0; i < 5; i++ {
		ch <- i
		fmt.Println("successfully wrote", i, "to ch")
	}
	close(ch)
}

// 23. 缓冲信道和工作池（Buffered Channels and Worker Pools）
func main(){
	ch1 := make(chan string, 2)//容量不够的时候就会报错 就是死锁
	ch1 <- "yang"
	ch1 <- "hao"
	fmt.Println(<- ch1)
	fmt.Println(<- ch1)
	fmt.Printf("\n")

	// 示例二
	ch2 := make(chan int, 2)
	go write(ch2)
	time.Sleep(2 * time.Second)
	for v := range ch2{
		fmt.Println("read value", v, "from ch2")
		time.Sleep(2 * time.Second)
	}

	// 长度 vs 容量
	// 缓冲信道的容量是指信道可以存储的值的数量 我们在使用 make 函数创建缓冲信道的时候会指定容量大小。
	// 缓冲信道的长度是指信道中当前排队的元素个数。
	ch3 := make(chan string, 3)
	ch3 <- "yang"
	ch3 <- "hao"
	fmt.Println("\ncapacity is", cap(ch3))
	fmt.Println("length is", len(ch3))
	fmt.Println("read value",<-ch3)
	fmt.Println("new length is", len(ch3))

	// WaitGroup 工作池
	no := 3
	var wg sync.WaitGroup
	for i := 0; i < no; i++ {
		wg.Add(1)
		go process(i, &wg)
	}
	wg.Wait()
	fmt.Println("All go routines finished executing")


}
func process(i int, wg *sync.WaitGroup) {
	fmt.Println("started Goroutine", i)
	time.Sleep(2 * time.Second)
	fmt.Printf("Goroutine %d ended\n",i)
	wg.Done()//减1 这里是加1 ==> wg.Add(1)
}